#pragma once
//#include <fstream>
//#include <allegro5/allegro_native_dialog.h>
#include <map>
#include "Tab2D.h"
#include "dataTypes.h"
#include "MapDrawer.h"
#include "Character.h"
#include "TileAction.h"
#include "ParticleSystem.h"
#include "LightSource.h"
#include "Weather.h"
using namespace std;

class MapDrawer;
class Weather;

class Map
{
	friend class MapDrawer;

public:
	Map(Character* aHero, int aSeed);
	~Map();

	void Tick();

	// setters and getters
	int GetTilesX() {return _tilesX;};
	int GetTilesY() {return _tilesY;};
	bool setLower(int aX, int aY, int aLower);
	bool setUpper(int aX, int aY, int aUpper);
	void setSeed(int aX, int aY, int aV);
	void setSpawn(int aX, int aY, int aJob);
	void SetPassable(int aX, int aY, bool aPass);
	void SetHero(Character* aHero);

	int getLower(int aX, int aY);
	int getUpper(int aX, int aY);
	int getSeed(int aX, int aY);
	int getSpawn(int aX, int aY);
	Tile getTile(int aX, int aY);
	Tile GetTile(int aX, int aY, int aDir);
	bool IsPassable(int aX, int aY, bool ignoreCharacters = false);
	bool IsValid(int aX, int aY);
	inline int getMapType(){return _mapType;};
	inline int getBiome(){return _biome;};

	vector<ParticleSystem*>* GetEffects() {return &effects;};
	vector<LightSource>* GetLightSpots() {return &lightSpots;};
	Weather* GetWeather() {return weather;};

	Character* GetHero() { return hero;};
	Node virtual GetHeroSpawn(int aFacing = -1) = 0;
	Character* GetCharacterAt(int aX, int aY);
	Character* GetHeroInterlocutor();

	TileAction* GetTileActionAt(int aX, int aY);
	TileAction* GetHeroTileAction();

	// maps navigation
	Map* parentMap;
	map<Node,Map*> childMaps;

	// global map UI
	//void save();
	//void load();

	// drawer cooperative
	inline bool hasChanged(){return _changed;};
	inline void refreshed(){_changed = false;};

	// global map functions
	void Generate(int aTilesX, int aTilesY);

protected:
	// main data
	int seed;
	int _tilesX;
	int _tilesY;
	Tab2D<Tile> _TileMap;
	vector<Character*> characters;
	Character* hero;
	vector<Node> occupiedTiles;
	vector<TileAction*> tileActions;
	vector<ParticleSystem*> effects;
	vector<LightSource> lightSpots;
	Weather* weather;

	int _mapType;		// World / City / Dungeon
	bool _changed;	// there's need for refresh?
	int _biome;			// Biome for City / Dungeon

	// transforming data
	void CreateCharacters();
	void CreateTileActions();
	void CreateQuests();
		Character* GetRandomCharacter(EJob aJob);
		void ApplyQuest(Quest* aQuest, Character* aCharacter);
	void virtual GenerateMapData() = 0;
};